home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / VB 'Wrappe237997312001.psc / ASPSocket.cls next >
Encoding:
Visual Basic class definition  |  2001-07-29  |  15.4 KB  |  441 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "ASPSocket"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = True
  14. Option Explicit
  15. '******************************************************'
  16. '------------------------------------------------------'
  17. ' Project: ASPSocket
  18. '
  19. ' Date: July-28-2001
  20. '
  21. ' Programmer: Antonio Ramirez Cobos
  22. '
  23. ' Description: Allows the implementation of a client socket
  24. '              to VB and ASP applications. It was designed
  25. '              with ASP programmers in mind, as other type
  26. '              of applications are better to be programmed by
  27. '              using other technologies such as Windows API
  28. '              for Sockets in order to improve VB to the limit.
  29. '              Nevertheless, I have included some event functionality
  30. '              for those wishing to test the object within VB
  31. '
  32. '              In addition, 'cause I consider myself in a continuous learning
  33. '              path with no end on programming, please, if you
  34. '              can improve this object [without using Sockets API]
  35. '              contact me at: *TONYDSPANIARD@HOTMAIL.COM*
  36. '
  37. '              I would be pleased to hear from your opinions,
  38. '              suggestions, and/or recommendations. Also, if you
  39. '              know something I don't know and wish to share it
  40. '              with me, here you'll have your techy pal from Spain
  41. '              that will do exactly the same towards you.
  42. '              Let's build a community of programmers helping
  43. '              programmers without the lucrative desire of fame
  44. '              on the back, let's just do it for *KNOWLEDGE*
  45. '              because that is real power.
  46. '
  47. '              INTELLECTUAL COPYRIGHT STUFF [Is up to you anyway]
  48. '              This code is copyright 2001 Antonio Ramirez Cobos
  49. '              This code may be reused and modified for non-commercial
  50. '              purposes only as long as credit is given to the author
  51. '              in the programmes about box and it's documentation.
  52. '              If you use this code, please email me at:
  53. '              TonyDSpaniard@hotmail.com and let me know what you think
  54. '              and what you are doing with it.
  55. '------------------------------------------------------'
  56. '******************************************************'
  57.  
  58. '-------- Private Properties
  59. Private m_propRemoteHost As String  '--- Host to connect to
  60. Private m_propRemotePort As Long '------ Port to connect to
  61. Private m_propLocalPort As Long '------- Local port [used mainly with SMTP]
  62. Private m_propReply As Boolean '-------- True if server sent data back
  63. Private m_propStatus As Sockets.SocketStatus '-- Socket status
  64. Private m_bytBuffer() As Byte '--------- Holds server sent data
  65. '------------------------------------------------------'
  66. '******************************************************'
  67.  
  68. '--------- The *WRAPPED* socket
  69. Private WithEvents Socket As Winsock
  70. Attribute Socket.VB_VarHelpID = -1
  71. '------------------------------------------------------'
  72. '******************************************************'
  73.  
  74. '--------- Events
  75. Event DataArrival(TotalBytes As Long) '--- Occurs when server sends data back
  76. Event Disconnected() '---- Occurs when server [close] connection
  77. Event Connected() '------- Occurs on connection
  78. '------------------------------------------------------'
  79. '******************************************************'
  80.  
  81.  
  82. '******************************************************'
  83. '------------------------------------------------------'
  84. ' Properties
  85. '
  86. ' RemoteHost: Host to connect to
  87. '
  88. Public Property Get RemoteHost() As String
  89.     RemoteHost = m_propRemoteHost
  90. End Property
  91. Public Property Let RemoteHost(Host As String)
  92.     m_propRemoteHost = Host
  93. End Property
  94. '
  95. '
  96. ' RemotePort: Port to connect to
  97. Public Property Get RemotePort() As Long
  98.     RemotePort = m_propRemotePort
  99. End Property
  100. Public Property Let RemotePort(Port As Long)
  101.     m_propRemotePort = Port
  102. End Property
  103. '
  104. '
  105. ' LocalPort: Local Port
  106. Public Property Get LocalPort() As Long
  107.     LocalPort = m_propLocalPort
  108. End Property
  109. Public Property Let LocalPort(Port As Long)
  110.     m_propLocalPort = Port
  111. End Property
  112. '
  113. '
  114. ' BytesReceived: Total Bytes on buffer received by the server
  115. Public Property Get BytesReceived() As Long
  116.     BytesReceived = UBound(m_bytBuffer)
  117. End Property
  118. '
  119. '
  120. ' Connected: True if connected, false otherwise
  121. Public Property Get Connected() As Boolean
  122.     Connected = (m_propStatus = scConnected)
  123. End Property
  124. '
  125. '
  126. ' LocalIP: Local IP address [Web Server were DLL sits]
  127. Public Property Get LocalIP() As String
  128.     LocalIP = Socket.LocalIP
  129. End Property
  130. '
  131. '
  132. ' LocalHostName: Computer name [Web Server were DLL sits]
  133. Public Property Get LocalHostName() As String
  134.     LocalHostName = Socket.LocalHostName
  135. End Property
  136. '
  137. '
  138. ' RemoteHostIP: Remote Host IP address [Server we are contacting]
  139. Public Property Get RemoteHostIP() As String
  140.     If m_propStatus <> scConnected Then Exit Property
  141.     RemoteHostIP = Socket.RemoteHostIP
  142. End Property
  143. '
  144. '
  145. ' SocketHandle: Included here for completeness but not very
  146. '               usefull for ASP. It is maily used for API
  147. Public Property Get SocketHandle() As Long
  148.     'This property was designed to be passed to Winsock APIs
  149.     SocketHandle = Socket.SocketHandle
  150. End Property
  151. '
  152. '
  153. ' ServerReply: True if data has been sent from the server we're
  154. '              connected
  155. Public Property Get ServerReply() As Boolean
  156.     ServerReply = m_propReply
  157. End Property
  158.  
  159. '******************************************************'
  160. '------------------------------------------------------'
  161. ' Methods
  162. '
  163. ' Connect: Tryes to connect to specified remote host and remote port
  164. '          during a specified Time interval [60 sec default]
  165. '
  166. ' Params: RHost=Remote Host;
  167. '         RPort= Remote Port;
  168. '         TimeOutInSec=Max. Interval of sec. to try
  169. Public Sub Connect(Optional RHost As String = R_HOST_NULL, Optional RPort As Long = PORT_NULL, Optional TimeOutInSec As Long = Minute)
  170.  
  171.     Dim Interval As Variant
  172.     
  173.     ' When using the object on an ASP page, the parameters are passed by
  174.     ' value, therefore the IsMissing statement is failing to return
  175.     ' appropriately. A solution is the one presented: setting parameters
  176.     ' to default values and check if the parameters hold different ones.
  177.     ' If the values holded by the parameters are the default ones, we
  178.     ' know the parameters had been omitted.
  179.     If Not RHost = R_HOST_NULL Then m_propRemoteHost = RHost
  180.     If Not RPort = PORT_NULL Then m_propRemotePort = RPort
  181.     
  182.     ' Make sure we are disconnected
  183.     If m_propStatus = scConnected Then
  184.         Disconnect
  185.     End If
  186.  
  187.     If m_propRemoteHost = "" Then Err.Raise vbObjectError, "ClientSocket:Connect()", "Host must be specified to connect"
  188.     
  189.     ' Check if we are going to send messages through
  190.     ' SMTP port
  191.     If m_propRemotePort = PORT_SMTP Then
  192.         '-- We must set local port to zero otherwise we'll not be
  193.         '   allowed to send more than one message -email-
  194.         If m_propLocalPort <> PORT_NULL Then m_propLocalPort = PORT_NULL
  195.         Socket.LocalPort = PORT_NULL
  196.     End If
  197.     
  198.     ' Try to connect to the server
  199.     m_propStatus = scConnecting
  200.     Socket.Connect m_propRemoteHost, m_propRemotePort
  201.     
  202.    Interval = Time + TimeOutInSec
  203.    
  204.    Do While m_propStatus = scConnecting And Interval > Time
  205.       '-- Loop for maximum interval of a minute to get an answer
  206.       '-- from the server
  207.       DoEvents
  208.    Loop
  209.     
  210.     ' If we didn't connect, raise an error
  211.     If m_propStatus <> scConnected Then
  212.         Socket.Close
  213.         DoEvents
  214.         If Err.Number <> 0 Then Err.Clear
  215.         m_propStatus = scClosed
  216.         Err.Raise vbObjectError, "ClientSocket.Connect()", "Couldn't connect"
  217.     End If
  218. End Sub
  219. '
  220. '
  221. ' Disconnect: Close connection to remote host
  222. Public Sub Disconnect()
  223.     ' Close the socket
  224.     If m_propStatus <> scClosed Then
  225.         On Error Resume Next
  226.         Socket.Close
  227.         DoEvents
  228.     End If
  229.     ' Update flag
  230.     m_propStatus = scClosed
  231.     
  232. End Sub
  233. '
  234. '
  235. ' Send: Sends data string to remote host
  236. Public Sub Send(Text As String)
  237.     Socket.SendData Text
  238. End Sub
  239. '
  240. '
  241. ' SendBinary: Sends binary data to the server
  242. '             Note: Do not use with ASP [sure crash even if
  243. '                   the parameter is variant data type!]
  244. 'Public Sub SendBinary(BytArray() As Byte)
  245. '    Socket.SendData BytArray
  246. 'End Sub
  247. '
  248. '
  249. ' GetData: Extracts and returns specified number of bytes as a string
  250. '          data type from the buffer if any data was sent from remote host
  251. '
  252. ' Params: NumberOfBytes=Number of bytes to extract
  253. Public Function GetData(Optional NumberOfBytes As Long = ALL_DATA) As String
  254.  
  255.     Dim TotalBytes As Long, Contents As String, intJ As Integer
  256.     
  257.     '------ how many bytes requested?
  258.     If NumberOfBytes <> ALL_DATA Then
  259.         TotalBytes = NumberOfBytes
  260.         If TotalBytes > UBound(m_bytBuffer) Then TotalBytes = UBound(m_bytBuffer)
  261.     Else
  262.         '--- none, return the whole lot
  263.         TotalBytes = UBound(m_bytBuffer)
  264.     End If
  265.     '--- If there is nothing to return get out of here
  266.     If TotalBytes < 1 Then
  267.         m_propReply = False
  268.         Exit Function
  269.     End If
  270.     
  271.     '--- Allocate space
  272.     Contents = String(TotalBytes + 1, " ")
  273.     
  274.     '--- Get the bytes
  275.     '--- [pretty cool way to copy from a byte array to a string isn't it?]
  276.     CopyMemory ByVal Contents, m_bytBuffer(0), TotalBytes + 1
  277.     
  278.     '--- Return data extracted
  279.     GetData = Contents
  280.     
  281.     '-- Move data to the beginning of the array [if any]
  282.     '   and resize array
  283.     If TotalBytes = UBound(m_bytBuffer) Then
  284.         '-- We read everything therefore
  285.         '   resize to zero
  286.         m_propReply = False ' End of Server Reply
  287.         ReDim m_bytBuffer(0)
  288.     Else
  289.         CopyMemory m_bytBuffer(0), m_bytBuffer(TotalBytes + 1), UBound(m_bytBuffer) - TotalBytes
  290.         ReDim Preserve m_bytBuffer(UBound(m_bytBuffer) - (TotalBytes + 1))
  291.     End If
  292. End Function
  293. '
  294. '
  295. ' GetBinaryData: Fills ByteArray parameter with NumberOfBytes requested. If
  296. '                NumberOfBytes hasn't been set, then ByteArray will be filled
  297. '                filled with all data stored on the buffer.
  298. '                Note: Do not use with ASP [sure crash even if
  299. '                      the parameter is variant data type!]
  300. 'Public Sub GetBinaryData(ByteArray() As Byte, Optional NumberOfBytes As Long = ALL_DATA)
  301. '
  302. '    Dim TotalBytes As Long, intJ As Integer
  303. '
  304. '    '-- Find out bytes requested
  305. '    If NumberOfBytes = ALL_DATA Then
  306. '        TotalBytes = UBound(m_bytBuffer)
  307. '    Else
  308. '        TotalBytes = NumberOfBytes
  309. '        ' Reduce TotalBytes if higher than actual buffer size
  310. '        If TotalBytes > UBound(m_bytBuffer) Then TotalBytes = UBound(m_bytBuffer)
  311. '    End If
  312. '    '-- There is no bytes, then get out of here
  313. '    If TotalBytes < 1 Then
  314. '        m_propReply = False
  315. '        Exit Sub
  316. '    End If
  317. '
  318. '    '-- Allocate space
  319. '    ReDim ByteArray(TotalBytes)
  320. '
  321. '    '---- Copy bytes accross
  322. '    CopyMemory ByteArray(0), m_bytBuffer(0), TotalBytes + 1
  323. '
  324. '    '-- Now resize buffer accordingly to the bytes extracted from it
  325. '    If TotalBytes = UBound(m_bytBuffer) Then
  326. '        m_propReply = False ' End of server reply
  327. '        ReDim m_bytBuffer(0)
  328. '    Else
  329. '        '--- Move non-extracted bytes to the front of the buffer
  330. '        '    and resize buffer
  331. '        CopyMemory m_bytBuffer(0), m_bytBuffer(TotalBytes + 1), UBound(m_bytBuffer) - (TotalBytes)
  332. '        ReDim Preserve m_bytBuffer(UBound(m_bytBuffer) - (TotalBytes + 1))
  333. '    End If
  334. '
  335. 'End Sub
  336. '
  337. '
  338. ' Do_Events: Helping ASP applications to apply this useful
  339. '            VB statement
  340. Public Sub Do_Events()
  341.     DoEvents
  342. End Sub
  343.  
  344. '******************************************************'
  345. '------------------------------------------------------'
  346. ' Object's main events
  347. '
  348. '
  349. Private Sub Class_Initialize()
  350.     Set Socket = New Winsock '[normal init.]
  351.     m_propRemotePort = PORT_HTTP '-- HTTP port by default [80]
  352.     m_propLocalPort = PORT_NULL '--- zero by default [random port selection]
  353.     m_propStatus = scClosed '--------- Closed
  354.     m_propReply = False '----------- Not server reply
  355.     ReDim m_bytBuffer(0) '---------- Init. Buffer that will hold all the data
  356. End Sub
  357.  
  358. Private Sub Class_Terminate()
  359.     On Error Resume Next
  360.     '--- If the socket hasn't been closed, then
  361.     '    close it!
  362.     If Socket.State <> sckClosed Then
  363.         Socket.Close
  364.         DoEvents
  365.     End If
  366.     Set Socket = Nothing
  367. End Sub
  368.  
  369. ' -------------------------------------------------------------- '
  370. ' *********************** WINSOCK EVENTS *********************** '
  371. '
  372. ' Note: For more info about this events check MSDN library
  373. '
  374. ' Socket_Close: Remote host closed the conncection
  375. Private Sub Socket_Close()
  376.     '-- server socket connection closed, close our connection
  377.     '   and raise the event to inform user about it
  378.     m_propStatus = scClosed
  379.     Socket.Close
  380.     DoEvents
  381.     RaiseEvent Disconnected
  382. End Sub
  383. '
  384. '
  385. ' Socket_Connect: Connection accepted
  386. Private Sub Socket_Connect()
  387.     '---- connection established, update flag and raise event
  388.     m_propStatus = scConnected
  389.     RaiseEvent Connected
  390. End Sub
  391. '
  392. '
  393. ' Socket_DataArrival: Remote host sent some data
  394. Private Sub Socket_DataArrival(ByVal bytesTotal As Long)
  395.     Dim bytTempBuffer() As Byte, intPos As Integer
  396.     
  397.     '---- Get data arrived
  398.     '     Resize temp buffer to store new incoming bytes of data
  399.     ReDim bytTempBuffer(bytesTotal)
  400.     
  401.     '---- Get the data as binary and store it in temporary
  402.     '     byte array
  403.     Socket.GetData bytTempBuffer, vbByte, bytesTotal
  404.     
  405.     '---- Add data at the buffer's first position *FREE* of data
  406.     If UBound(m_bytBuffer) = 0 Then
  407.         intPos = 0
  408.     Else
  409.         intPos = UBound(m_bytBuffer) + 1
  410.     End If
  411.     
  412.     '---- Now resize buffer holding the whole sent information [past-present]
  413.     '     to hold new bytes
  414.     ReDim Preserve m_bytBuffer(intPos + bytesTotal)
  415.     '---- Copy in one shot [thanks to CopyMemory function]
  416.     CopyMemory m_bytBuffer(intPos), bytTempBuffer(0), bytesTotal
  417.     '--- We had a reply, Communicate this to the user
  418.     m_propReply = True
  419.     '---- RAISE EVENT [If object is been used on a VB application, absurd
  420.     '     as we have Windows API and Winsock control to do the job, but anyway is here]
  421.     RaiseEvent DataArrival(UBound(m_bytBuffer))
  422. End Sub
  423. '
  424. '
  425. ' Socket_Error: [Needs definition?]
  426. Private Sub Socket_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
  427.     '--- If we are not trying to connect
  428.     '    raise an error returning the error number & description
  429.     If m_propStatus <> scConnecting Then
  430.         m_propStatus = scError
  431.         '--- Raise the event [*POINTLESS* for an ASP Application]
  432.         RaiseEvent Disconnected
  433.         If m_propStatus = scConnected Then Socket.Close
  434.         Err.Raise Number, "ClientSocket:Error()", Description
  435.     Else '- Connecting
  436.         '-- Update flag to stop looping on connection procedure
  437.         m_propStatus = scError
  438.     End If
  439. End Sub
  440. ' ******************** END OF WINSOCK EVENTS *********************
  441.